package top.xia17.plugins.fast.common.database.jpa.extension;

import top.xia17.plugins.fast.common.database.CrudServiceExpand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import top.xia17.plugins.fast.common.model.BaseMapstruct;

import java.util.List;
import java.util.Optional;

/**
 * 基础service实现
 * 该版本添加DTO相关的接口
 *
 * @author xia17
 * @since 2021/7/14 11:39
 */
public class JpaDtoServiceImpl<T extends JpaEntity<ID>, D, ID, R extends Xia17JpaRepository<T,
        ID>, M extends BaseMapstruct<D, T>> extends JpaServiceImpl<T, ID, R> implements JpaDtoService<T, D, ID>,
        CrudServiceExpand<T> {

    @SuppressWarnings("all")
    @Autowired
    protected M baseMapstruct;

    public M getBaseMapstruct() {
        return baseMapstruct;
    }

    @Override
    public Optional<D> findDtoById(ID id) {
        return this.findById(id).map(baseMapstruct::toDto);
    }

    @Override
    public D findDtoByIdOrThrow(ID id) {
        return baseMapstruct.toDto(this.findByIdOrThrow(id));
    }

    @Override
    public List<D> findAllDto(Specification<T> query) {
        return baseMapstruct.toDto(this.findAll(query));
    }

    @Override
    public List<D> findAllDtoById(Iterable<ID> ids) {
        return baseMapstruct.toDto(this.findAllById(ids));
    }

    @Override
    public Page<D> findAllDto(Specification<T> query, Pageable pageable) {
        return this.findAll(query, pageable).map(baseMapstruct::toDto);
    }

    @Override
    public Optional<D> findOneDto(Specification<T> query) {
        return this.findOne(query).map(baseMapstruct::toDto);
    }

    @Override
    public D findOneDtoOrThrow(Specification<T> query) {
        return baseMapstruct.toDto(this.findOneOrThrow(query));
    }

    @Override
    public D createDto(T resource) {
        T t = this.create(resource);
        return baseMapstruct.toDto(t);
    }

    @Override
    public D updateDto(T resource) {
        T t = this.update(resource);
        return baseMapstruct.toDto(t);
    }
}
